package com.unity.notificationbackground;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import java.util.HashMap;
import java.util.Map;

public class AndroidBackgroundNotificationManager {

    public static final int RETURN_NONE = -1;
    public static final int RETURN_APP = 0;
    public static final int RETURN_NET = 1;

    private Context _context;
    private Activity _activity;
    private Intent _intent;
    private NotificationManager _notificationManager;
    private static AndroidBackgroundNotificationManager _instance;
    public static final String DefaultChannel = "000";

    public static AndroidBackgroundNotificationManager GetInstance() {
        return _instance;
    }

    private HashMap<Integer, BackgroundNotificationTask> MapProgressAsyncTask = new HashMap<Integer, BackgroundNotificationTask>();

    public AndroidBackgroundNotificationManager(Activity activity) {
        _instance = this;
        _activity = activity;
        _context = activity.getApplicationContext();
        _intent = _activity.getIntent();
        _notificationManager = GetNotificationManager(_context);
        RegisterNotificationChannel(DefaultChannel);
    }

    public void ScheduleBackgroundNotification(IBackgroundNotification progressNotify) {
        if (MapProgressAsyncTask.containsKey(progressNotify.GetId())) {
            if (!MapProgressAsyncTask.get(progressNotify.GetId()).isCancelled())
            {
                return;
            }
            MapProgressAsyncTask.remove(progressNotify.GetId());
        }
        BackgroundNotificationTask task = new BackgroundNotificationTask(progressNotify);
        MapProgressAsyncTask.put(progressNotify.GetId(), task);
        task.execute(1000);
    }

    public void CancelScheduleBackgroundNotification(IBackgroundNotification progressNotify) {
        if (!MapProgressAsyncTask.containsKey(progressNotify.GetId())) {
            return;
        }
        BackgroundNotificationTask task = MapProgressAsyncTask.get(progressNotify.GetId());
        MapProgressAsyncTask.remove(progressNotify.GetId());
        task.cancel(true);
        CancelDisplayedNotification(progressNotify.GetId());
    }

    public void CancelAllScheduleBackgroundNotification() {
        for (Map.Entry<Integer, BackgroundNotificationTask> entry : MapProgressAsyncTask.entrySet()) {
            entry.getValue().cancel(true);
            CancelDisplayedNotification(entry.getKey());
        }
        MapProgressAsyncTask.clear();
    }


    @SuppressWarnings("deprecation")
    public Notification.Builder SendNotification(String title, String content) {
        int id = 0;
        Notification.Builder builder;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            builder = new Notification.Builder(_context);
        } else {
            builder = new Notification.Builder(_context, DefaultChannel);
        }
        builder.setContentTitle(title);
        builder.setContentText(content);
        builder.setSmallIcon(GetDefaultAppIcon());
        builder.setPriority(Notification.PRIORITY_HIGH);
        builder.setAutoCancel(true);
        _notificationManager.notify(id, builder.build());
        return builder;
    }

    public void CancelDisplayedNotification(int id) {
        _notificationManager.cancel(id);
    }

    // Cancel all previously shown notifications.
    public void CancelAllNotifications() {
        CancelAllScheduleBackgroundNotification();
        _notificationManager.cancelAll();
    }

    public void RegisterNotificationChannel(String id) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(id, id, NotificationManager.IMPORTANCE_HIGH);
            channel.setLockscreenVisibility(LockScreenVisibility.EPublic);
            _notificationManager.createNotificationChannel(channel);
        }
    }

    public int GetDefaultAppIcon() {
        return GetDefaultAppIcon(_context);
    }

    public void SendBackgroundNotification(IBackgroundNotification progressNotify) {
        _notificationManager.notify(progressNotify.GetId(), NewNotifyCationBuilder(progressNotify).build());
    }

    public Notification.Builder NewNotifyCationBuilder(IBackgroundNotification progressNotify) {
        int id = progressNotify.GetId();
        Notification.Builder builder;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            builder = new Notification.Builder(_context);
        } else {
            builder = new Notification.Builder(_context, DefaultChannel);
        }
        if (progressNotify.GetAppSmallIcon() >0) {
            builder.setSmallIcon(progressNotify.GetAppSmallIcon());
        } else {
            builder.setSmallIcon(GetDefaultAppIcon());
        }

        PendingIntent pendingIntent;
        if (progressNotify.GetReturnAction() == RETURN_NET) {
            pendingIntent = GetActivityPendingIntent(_activity, id, GetOpenWifiIntent(), 0);
        } else {
            pendingIntent = GetActivityPendingIntent(_activity, id, GetOpenAppIntent(), 0);
        }
        if (NeedShowProgress(progressNotify))
        {
            builder.setProgress(100,progressNotify.GetProgress(),false);
        }
        builder.setContentTitle(progressNotify.GetTitle());
        builder.setContentText(progressNotify.GetContent());
        builder.setTicker(progressNotify.GetTitle());
        builder.setContentIntent(pendingIntent);
        builder.setPriority(Notification.PRIORITY_HIGH);
        builder.setAutoCancel(true);
        builder.setOngoing(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            builder.setFlag(Notification.FLAG_NO_CLEAR, true);
        }
        return builder;
    }

    private Intent GetOpenWifiIntent() {
        return new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
    }

    public Intent GetOpenAppIntent() {
        Intent openAppIntent = new Intent(_context, _activity.getClass());
        openAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        return openAppIntent;
    }

    public static NotificationManager GetNotificationManager(Context context) {
        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    public static int GetDefaultAppIcon(Context context) {
        return context.getApplicationInfo().icon;
    }

    public static PendingIntent GetActivityPendingIntent(Context context, int id, Intent intent, int flags) {
        if (Build.VERSION.SDK_INT >= 23)
            return PendingIntent.getActivity(context, id, intent, flags | PendingIntent.FLAG_IMMUTABLE);
        else
            return PendingIntent.getActivity(context, id, intent, flags);
    }

    public static AndroidBackgroundNotificationManager NotificationManagerImpl(Activity activity) {
        return new AndroidBackgroundNotificationManager(activity);
    }

    public static boolean NeedShowProgress(IBackgroundNotification progressNotify) {
        return progressNotify.NeedShowProgress();
    }
}
